iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0
Vibe Coding

從 GAS 到 Cloudflare D1:AI Agent 如何打造、接手並重構真實便當系統系列 第 2

Day 2|不是先寫 Code:我怎麼把舊便當系統拆成可移轉的需求清單?

  • 分享至 

  • xImage
  •  

Day2

上一篇提到,這套便當系統不是從 GAS、React 或 Cloudflare 開始的。

在那些東西出現以前,公司裡就已經有一套真的有人在用的內部訂餐系統。

它可以:

  • 預訂未來 21 天的便當
  • 查看過去 7 天的歷史訂購
  • 統計不同取餐樓層的數量
  • 查看當日每種餐點的訂購數
  • 後來也加入了預付餘額

當我決定做新的手機版時,第一個問題不是:

我要用什麼框架?

也不是:

要不要用 React?

而是:

舊系統裡,到底有哪些行為是新版不能弄丟的?

如果這件事沒有先搞清楚,重做很容易變成:

畫面更漂亮了,
技術更新了,
但使用者原本習慣的流程卻壞掉了。

我後來才慢慢發現:

重做 Legacy System,第一步不是先寫 Code,而是先把需求從舊系統裡挖出來。


畫面不是需求,只是需求留下來的痕跡

拿 Day 1 的舊畫面來看,乍看之下很簡單。

例如訂餐頁可能只看到:

  • 日期
  • 餐點
  • 姓名
  • 取餐樓層
  • 餘額

如果只是照著畫面重做,很容易理解成:

好,那新版把這些欄位做出來就好了。

但開始移轉之後,問題會變成完全不同的樣子。

例如:

「姓名」只是顯示文字嗎?

如果未來開始有登入機制,那姓名到底是:

  • 使用者的身份?
  • 只是顯示名稱?
  • 可以自己修改嗎?
  • 如果兩個人同名怎麼辦?

原本舊系統可能完全不需要回答這些問題。

因為在當時的使用環境裡,大家知道「這個名字是誰」。

但一旦系統開始往手機、登入、身份綁定走,

這個原本看起來只是一個文字欄位的東西,就會變成身份模型的一部分。


「取餐樓層」也不是普通欄位

舊系統裡有取餐樓層。

看起來只是:

1F
9F

但它背後其實連著實際流程。

因為最後便當不是只要知道總共有幾份。

還需要知道:

1 樓要幾份?
9 樓要幾份?

這會直接影響最後的發餐方式。

移轉時要保留的不是:

資料庫裡有一個 floor 欄位。

而是:

統計結果必須能依取餐樓層正確分組。

兩者看起來很像,實際上完全不同。

前者是資料結構。

後者才是 Business Rule。


當日統計也不只是 SUM()

Day 1 的另一張畫面,是當日訂餐統計。

表面上看起來可能只是:

某餐點:5
另一餐點:8
1F:6
9F:7

技術上可能只是幾個 SUM()GROUP BY

但這個頁面的用途是:

它的數字最後會被拿來向店家下單。

這件事讓它從「統計畫面」變成會直接影響日常流程的資料。

如果統計錯一份,

結果不是 Dashboard 長得不好看,

而是真的可能有一個人沒便當吃。

如果要重新整理需求,我會把:

功能:顯示統計

改寫成:

對指定日期的有效訂單進行統計,
依餐點與取餐樓層彙總,
並作為實際向店家下單的依據。

這就是我後來很重視的一件事:

不要只記錄畫面做什麼,要記錄這個畫面為什麼存在。


最容易低估的是「餘額」

舊系統後來加入預付餘額。

一開始需求非常單純:

大家一次先繳一些錢,訂便當就從裡面扣。

畫面上可能就只是一個數字:

餘額:700

如果只看 UI,很容易把需求理解成:

使用者有一個 balance 欄位。

訂餐時:

balance = balance - price

取消時:

balance = balance + price

看起來好像就結束了。

但實際維護之後,就會開始出現問題:

  • 這 700 元是怎麼來的?
  • 哪一天儲值?
  • 訂了哪一餐扣掉多少?
  • 訂單取消後有沒有加回去?
  • 管理員有沒有手動調整過?
  • 如果畫面顯示 700,但歷史加總算出來是 600,哪一個才該相信?

這時候才會發現:

「餘額」不是一個數字,而是一段歷史的結果。

這個觀念後來也直接影響我之後怎麼設計 Balance Ledger。

但在第一次移轉時,我還沒有把事情做到這麼完整。

當時更重要的是先意識到:

這個看起來只有一欄的功能,不能只當成一欄資料搬過去。


我後來把需求拆成四種類型

為了避免「看到什麼就重做什麼」,我現在會把需求分成四類。

這個分類不只適用便當系統,很多 Legacy Migration 也能拿來用。

1. Must Keep:一定不能弄丟的既有行為

這些是使用者已經依賴的功能。

例如:

  • 預訂未來日期
  • 查看近期歷史訂單
  • 依取餐樓層統計
  • 顯示當日餐點數量
  • 保存使用者餘額

這一類的重點不是:

介面要長得一樣。

而是:

新版必須保留同樣的業務結果。


2. Improve:可以改善,但不能改壞流程

有些東西是舊系統可以用,但新版本有機會做得更好。

例如:

  • 手機操作
  • 菜單呈現
  • 圖片
  • 操作步驟
  • 管理員查看方式

這類需求可以重新設計。

但改善前還是要問:

使用者原本為什麼這樣操作?

不要只是因為新版比較漂亮,就把原本有效率的流程改掉。


3. New:舊系統根本沒有的新需求

這些是推動重做的原因。

例如:

  • 多店家
  • 手機使用
  • 外部存取
  • 後來的 LINE 身份
  • 更完整的權限模型

這一類不能假裝成 Legacy Parity。

它就是新的需求。

而新需求越多,

越代表這次不是單純移植。

而是:

在保留舊行為的前提下,重新定義下一版系統。


4. Non-goal:這次明確不做什麼

這一類反而很重要。

因為一旦開始重做,很容易冒出很多:

既然都要做了,不然順便……

例如:

  • 順便做完整庫存
  • 順便串第三方付款
  • 順便做店家後台
  • 順便做完整財務系統
  • 順便把所有歷史資料全部重新整理

每一個都好像有道理。

但全部一起做,第一版通常永遠出不來。

更實際的做法是:

先把「下一版一定要解決什麼」和「現在不要解決什麼」切清楚。

這也是後來我在 Agent Workflow 裡很常用 Explicit Exclusions 的原因。

範圍沒有寫清楚,

人會順手多做,

AI Agent 更會。


我會把需求整理成這種表

如果把當時的舊系統重新整理一次,大概會像這樣:

舊系統能力 表面上看到的功能 要保留的規則 分類
未來 21 天訂餐 日期選擇 只能在允許的日期範圍內下單 Must Keep
過去 7 天紀錄 歷史查詢 已發生訂單必須能追溯 Must Keep
取餐樓層 1F / 9F 統計必須依實際取餐樓層分組 Must Keep
當日統計 數量統計 數字會直接作為店家下單依據 Must Keep
預付餘額 一個金額 訂餐、取消後金額必須一致 Must Keep
手機使用 新介面 不再依賴固定公司電腦 New
多店家 店家選擇 店家、菜單、價格不再是固定值 New
UI 重整 畫面改善 不影響既有訂餐流程 Improve

這張表對我來說,比先畫新版 UI 更重要。

因為它開始把:

舊網站長什麼樣

轉成:

新版必須保證什麼。


再往下一步,就是 Acceptance Criteria

只有「需求」還不夠。

像這種描述:

取餐樓層要正常。

幾乎沒辦法驗收。

如果要真的拿來重做,我會希望它至少變成:

Given
使用者的取餐樓層為 9F

When
使用者成功提交一份便當訂單

Then
該訂單保存 pickup_floor = 9F

And
當日統計的 9F 數量增加 1

And
1F 的統計數量不受影響

這就從一個模糊的需求,

變成可以驗收、也可以測試的行為。

同樣的概念也可以套到餘額:

Given
使用者目前餘額為 500 元

When
成功訂購一份 100 元便當

Then
訂單成功建立

And
剩餘餘額為 400 元

如果還有取消流程:

Given
該 100 元訂單已成立

When
在允許取消的條件下成功取消

Then
訂單狀態變更

And
100 元必須正確回到使用者餘額

當需求開始寫到這個程度,

它才開始具備「可以移轉」的條件。


這件事到了 AI Agent 時代反而更重要

如果今天完全人工重寫,

工程師在做的時候可能還會邊看、邊問、邊修。

但如果把需求直接丟給 AI Agent:

幫我把舊訂餐網站重做成手機版。

它很可能做出一個:

看起來完全合理,但行為已經變掉的系統。

因為 AI 看得到:

  • UI
  • Code
  • Schema

但它不一定知道這個欄位為什麼存在,也不知道哪個看起來很奇怪的行為,可能正是公司已經用了兩年的流程。

到了 AI 時代,我反而更重視一件事:

把「不能被猜錯的東西」寫下來。

而且不一定要寫成幾十頁需求文件。

有時候一張 Feature Inventory,

幾條 Business Rule,

加幾個 Acceptance Criteria,

就已經能大幅降低重做時的誤差。


Day 2 留下的做法

如果把今天這篇濃縮成一個流程,我現在會這樣做:

1. 看舊系統

2. 列 Feature Inventory

3. 找 Hidden Business Rules

4. 分成 Must Keep / Improve / New / Non-goal

5. 重要行為寫成 Acceptance Criteria

6. 最後才開始重新選技術與實作

這比:

看一下舊畫面

開始寫新版

慢一點。

但通常會少掉很多後面的返工。

尤其當舊系統已經有人在用、有正式資料、有歷史流程時,

這個步驟的重要性會變得更高。

因為不能弄丟的不是舊畫面的 CSS,而是那些已經存在於系統和使用者之間、卻從來沒有人正式寫下來的規則。


下一篇

需求盤點完成之後,才輪到技術選擇。

當時我要的很簡單:

  • 手機可以用
  • 開發速度快
  • 資料方便查看
  • 不想一開始就架一套完整 Backend

第一版手機化最後選擇了:

Google Apps Script + Google Sheets。

下一篇就來看:

Day 3|第一版手機化,為什麼我會選 GAS + Google Sheets?


上一篇
Day 1|我只是想訂便當,怎麼最後做成一套正式系統?
下一篇
Day 3|為什麼第一版手機版便當系統,我選了 GAS + Google Sheets?
系列文
從 GAS 到 Cloudflare D1:AI Agent 如何打造、接手並重構真實便當系統9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言